 /*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.mygameframework.isoengine;

import com.mygameframework.scenes.CommonScene;
import com.mygameframework.scenes.IRenderable;
import com.mygameframework.test.CustomScene1;
import com.mygameframework.util.Utility;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.nio.channels.ClosedByInterruptException;

/**
 *
 * @author sa
 */
public class Renderer {
    IRenderable scene;
    TileEngine te;
    Scroller scroller;
    TilePlotter plotter;
    TileWalker walker;
    MouseMapper mmp;
    int mapWidth,mapHeight;
    BufferedImage frameBuffer;
    Graphics2D gFrameBuffer;
    /*由IRenderable　实现类提供*/
    BufferedImage offScreenImage;
    Graphics2D gOffScreen;
//    Graphics2D gFrameBuffer;
    int maxUpdateCaptical=100;//default
    int iUpdateRectIdx;
    Rectangle[] updateBoxes=new Rectangle[maxUpdateCaptical];
    Rectangle rcExtent;
    private boolean extremeEfficiency=true;
    private  int scale=1;//重绘区域的水平和垂直扩展的数长,一般不少于1步 
    
    
    boolean[] bMap=new boolean[mapWidth * mapHeight];
    

    public Renderer(TileEngine te,IRenderable scene) {
        this.scene=scene;
        this.offScreenImage=scene.getOffScreenImage();
        this.gOffScreen=scene.getOffScreenGraphics();
        frameBuffer=Utility.createCompatibleImage(offScreenImage);
        gFrameBuffer=frameBuffer.createGraphics();
        this.te = te;
        scroller=te.getScroller();
        plotter=te.getPlotter();
        walker=te.getWalker();
        mmp=te.getMouseMapper();
        
        mapWidth=te.getMapWidth();
        mapHeight=te.getMapHeight();
        int c=mapWidth * mapHeight;
        System.out.println("[renderer.构造] 布尔数组长度: "+c);
        bMap=new boolean[c];
//        arrUpdateRect=new Rectangle[maxUpdateCaptical];
    }

//    public Renderer(Scroller scroller, TilePlotter plotter, TileWalker walker, MouseMapper mmp) {
//        this.scroller = scroller;
//        this.plotter = plotter;
//        this.walker = walker;
//        this.mmp = mmp;
//        bMap=new boolean[scroller.getMapWidth() * scroller.getMapHeight()];
//    }
    
    public Renderer() {
        
    }

    public boolean isExtremeEfficiency() {
        return extremeEfficiency;
    }


//    public void setFrameBuffer(BufferedImage frameBuffer){
//        this.frameBuffer=frameBuffer;
//    }
//    public void setBackBuffer(BufferedImage backBuffer){
//        this.backBuffer=backBuffer;
//    }
    public void setMapHeight(int mapHeight) {
        this.mapHeight = mapHeight;
    }

    public void setMapWidth(int mapWidth) {
        this.mapWidth = mapWidth;
    }

    public void setRcExtent(Rectangle rcExtent) {
        this.rcExtent = rcExtent;
    }

    public Rectangle getRcExtent() {
        return rcExtent;
    }
    
//    public void setMmp(MouseMapper mmp) {
//        this.mmp = mmp;
//    }
//
//    public void setPlotter(TilePlotter plotter) {
//        this.plotter = plotter;
//    }
//
//    public void setScroller(Scroller scroller) {
//        this.scroller = scroller;
//    }
//
//    public void setWalker(TileWalker walker) {
//        this.walker = walker;
//    }
    public void scrollFrame(int dx,int dy){
        if(!extremeEfficiency)throw new IllegalStateException("for invoke addRect() ,boolean extremeEfficiency must be true");
        if(dx==0 && dy ==0) return;
        
        Point ptAnchorOld=new Point(te.getScreenAnchor());
        te.moveScreenAnchor(dx, dy, true);//考虑到可能视窗被ScreenSpace各种限制,
//        System.out.println(te.getScreenAnchor());
        dx=te.getScreenAnchorX()-ptAnchorOld.x;//如Wrap/limit...
        dy=te.getScreenAnchorY()-ptAnchorOld.y;//这样能取得实际位移
        te.setScreenAnchor(ptAnchorOld.x, ptAnchorOld.y);//reset
        
        Rectangle rcSrc;//frameBuffer中要移的区域,(移到backBuffer)
        Rectangle rcDst;//frameBuffer局部图移图将移到(backBuffer的)新区域
        Rectangle sp=te.getScreenSpace();
        Rectangle rcUpdateX=new Rectangle();
        Rectangle rcUpdateY=new Rectangle();
        rcSrc=  new Rectangle(te.getScreenSpace());
        rcDst=new Rectangle(te.getScreenSpace());
        if(dx!=0){
            if(dx<0){//srcoll to left
		//positive scrollx  负的,视窗左移
                //scroll direction: to the right 原帧(画面)右移
                //set up an update rect for the left side of the screen 更新在左
//                rcUpdateX.setRect(rcDst.x, rcDst.y, -dx, rcDst.height);
//                rcDst.setRect(rcDst.x-dx, rcDst.y, rcDst.width+dx, rcDst.height);
//                rcSrc.setRect(rcSrc.x, rcSrc.y, rcSrc.width+dx, rcSrc.height);
                
                
//                gOffScreen.copyArea(sp.x,sp.y,
//                        sp.width, sp.height,         -dx,0);
                
                gOffScreen.copyArea(sp.x,sp.y,
                        sp.width+dx, sp.height,         -dx,0);
                
//                gFrameBuffer.copyArea(sp.x,sp.y,
//                        sp.width+dx, sp.height,-dx,0);
                rcUpdateX.setRect(sp.x, sp.y, -dx, sp.height);
            }else{//srcoll to right
                //正的,视窗右移  //原帧(画面)左移 //更新在右
//                rcUpdateX.setRect(rcDst.getMaxX()-dx, rcDst.y, dx, mapHeight);
//                rcDst.setRect(rcDst.x,rcDst.y, rcDst.width-dx, rcDst.height);
//                rcSrc.setRect(rcSrc.x+dx, rcSrc.y, rcSrc.width-dx, rcSrc.height);
                
//                gOffScreen.copyArea(sp.x,sp.y,
//                        sp.width, sp.height,         -dx,0);
                
                gOffScreen.copyArea(sp.x+dx,sp.y,
                        sp.width-dx, sp.height,         -dx,0);
                
//                gFrameBuffer.copyArea(sp.x+dx,sp.y,
//                        sp.width-dx, mapHeight,-dx,0);
                rcUpdateX.setRect(sp.getMaxX()-dx, sp.y, dx, sp.height);
            }
        }
        if(dy!=0){
            if(dy<0){
                //负的,视窗上移//原帧(画面)下//更新在上
//                rcUpdateY.setRect(rcDst.x, rcDst.y, rcDst.width, -dy);
//                rcDst.setRect(rcDst.x,rcDst.y-dy,rcDst.width,rcDst.height+dy);
//                rcSrc.setRect(rcSrc.x, rcSrc.y ,rcSrc.width, rcSrc.height+dy);

//                gOffScreen.copyArea(sp.x,sp.y,
//                        sp.width, sp.height,0,-dy);
                
                gOffScreen.copyArea(sp.x,sp.y,
                        sp.width, sp.height+dy,0,-dy);
                
//                gFrameBuffer.copyArea(sp.x, sp.y,
//                        sp.width, sp.height + dy, 0, -dy);
                rcUpdateY.setRect(sp.x, sp.y, sp.width,-dy);
                
            }else{
                //正的,视窗下移//原帧(画面)上//更新在下
//                rcUpdateY.setRect(rcDst.x, rcDst.getMaxY()-dy, rcDst.width,dy);
//                rcDst.setRect(rcDst.x,rcDst.y,rcDst.width,rcDst.height-dy);
//                rcSrc.setRect(rcSrc.x, rcSrc.y+dy ,rcSrc.width, rcSrc.height-dy);
                
//                gOffScreen.copyArea(sp.x,sp.y,
//                        sp.width, sp.height,0,-dy);
                
                gOffScreen.copyArea(sp.x,sp.y+dy,
                        sp.width, sp.height-dy,0,-dy);
                
//                gFrameBuffer.copyArea(sp.x, sp.y + dy,
//                        sp.width, mapHeight - dy, 0, -dy);
                rcUpdateY.setRect(sp.x, sp.getMaxY()-dy, sp.width,dy);
            }
        }
//        Graphics2D gback=backBuffer.createGraphics();
//        gback.drawImage(frameBuffer,
//                rcDst.x, rcDst.y, (int)rcDst.getMaxX(),(int) rcDst.getMaxY(),
//                rcSrc.x , rcSrc.y,(int)rcSrc.getMaxX(), (int)rcSrc.getMaxY(), null);
        //TODO 这句好像多余,前面不要RESET
        te.getScroller().moveScreenAnchor(dx, dy, true);
//        addRect(te.getScreenSpace());
//        System.out.println(te.getScreenSpace());
//        if(!rcUpdateY.isEmpty())
//        System.out.println(rcUpdateY);
        
        addRect(rcUpdateX);
        addRect(rcUpdateY);
        
    }//scrollFrame end
    public boolean addTile(int mapX,int mapY,Rectangle rcExt){
        Point ptMap=new Point(mapX, mapY);
        Point ptPlot=te.plot(ptMap);
        ptPlot=te.getScroller().worldToScreen(ptPlot);
        Rectangle rcUpdate=new Rectangle(te.getTileWidth(), te.getTileHeight());
        if(this.rcExtent!=null)
        rcUpdate=new Rectangle(rcExtent);
        if(rcExt!=null )
            rcUpdate=new Rectangle(rcExt);
        
        rcUpdate.translate(ptPlot.x,ptPlot.y);
        return addRect(rcUpdate);
    }
    public boolean addTile(int mapX,int mapY){
        return addTile(mapX,mapY,null);
    }
    
    public boolean addRect(Rectangle rect){
        if(!extremeEfficiency){
//            throw new IllegalStateException("for invoke addRect() ,boolean extremeEfficiency must be true");
            return false;
        }
        if(iUpdateRectIdx>=maxUpdateCaptical) {
            throw new IndexOutOfBoundsException("updateBox has bursted!:(");
        }
        
        Rectangle rcUpdate=rect.intersection(te.getScreenSpace());
        if(rcUpdate.isEmpty()) return false;
        
//        Color oldc=gOffScreen.getColor();
//        gOffScreen.setColor(Color.BLACK);//TODO 背景色 
//        gOffScreen.fillRect(rcUpdate.x, rcUpdate.y, rcUpdate.width, rcUpdate.height);
//        gOffScreen.setColor(oldc);
        
        
//        Rectangle s = te.getScreenSpace();
//        Color oldc = gFrameBuffer.getColor();
//        gFrameBuffer.setColor(Color.BLACK);//TODO 背景色 
//        gFrameBuffer.fillRect(0, 0, frameBuffer.getWidth(),frameBuffer.getHeight());
//        gFrameBuffer.setColor(oldc);
            
        Color oldc = gFrameBuffer.getColor();
        gFrameBuffer.setColor(Color.BLACK);
        gFrameBuffer.fillRect(rcUpdate.x, rcUpdate.y, rcUpdate.width, rcUpdate.height);
        gFrameBuffer.setColor(oldc);
        
        updateBoxes[iUpdateRectIdx]=rcUpdate;
        iUpdateRectIdx++;
        
        
        Point ptCornerUpperLeft = new Point();
        Point ptCornerUpperRight = new Point();
        Point ptCornerLowerLeft = new Point();
        Point ptCornerLowerRight = new Point();

        Point ptTmp = new Point();
        Point ptCoarse = new Point();
        Point ptMap = new Point();
        //=================左上=================
        ptTmp.x = rcUpdate.x;
        ptTmp.y = rcUpdate.y;
        /////
        ptTmp = te.getScroller().screenToWorld(ptTmp);
        ptTmp.x -= te.getMouseMapper().getOrigin().x;
        ptTmp.y -= te.getMouseMapper().getOrigin().y;
        ptCoarse.x = ptTmp.x / mmp.getTileWidth();
        ptCoarse.y = ptTmp.y / mmp.getTileHeight();
        ptTmp.x %= te.getMouseMapper().getTileWidth();
        ptTmp.y %= te.getMouseMapper().getTileHeight();
        if (ptTmp.x < 0) {
            ptCoarse.x--;
        }
        if (ptTmp.y < 0) {
            ptCoarse.y--;
        }
        //指定左上角点MAP(coarse)/////////
        ptMap.x = 0;
        ptMap.y = 0;
        ptMap = walker.tileWalk(ptMap, Direction.EAST);
        ptCornerUpperLeft.x = ptMap.x * ptCoarse.x;
        ptCornerUpperLeft.y = ptMap.y * ptCoarse.x;
        ptMap.x = 0;
        ptMap.y = 0;
        ptMap = walker.tileWalk(ptMap, Direction.SOUTH);
        ptCornerUpperLeft.x += (ptMap.x * ptCoarse.y);
        ptCornerUpperLeft.y += (ptMap.y * ptCoarse.y);
        //=================右上=================
        ptTmp.x = (int) rcUpdate.getMaxX();
        ptTmp.y = rcUpdate.y;
        ///////
        ptTmp = scroller.screenToWorld(ptTmp);
        ptTmp.x -= mmp.getOrigin().x;
        ptTmp.y -= mmp.getOrigin().y;
        ptCoarse.x = ptTmp.x / mmp.getTileWidth();
        ptCoarse.y = ptTmp.y / mmp.getTileHeight();
        ptTmp.x %= mmp.getTileWidth();
        ptTmp.y %= mmp.getTileHeight();
        if (ptTmp.x < 0) {
            ptCoarse.x--;
        }
        if (ptTmp.y < 0) {
            ptCoarse.y--;
        }
        //指定右上角点MAP(coarse)/////////
        ptMap.x = 0;
        ptMap.y = 0;
        ptMap = walker.tileWalk(ptMap, Direction.EAST);
        ptCornerUpperRight.x = ptMap.x * ptCoarse.x;
        ptCornerUpperRight.y = ptMap.y * ptCoarse.x;
        ptMap.x = 0;
        ptMap.y = 0;
        //move to the south
        ptMap = walker.tileWalk(ptMap, Direction.SOUTH);
        ptCornerUpperRight.x += (ptMap.x * ptCoarse.y);
        ptCornerUpperRight.y += (ptMap.y * ptCoarse.y);
        //=================左下=================
        ptTmp.x = rcUpdate.x;
        ptTmp.y = (int) rcUpdate.getMaxY();
        ////
        ptTmp = scroller.screenToWorld(ptTmp);
        ptTmp.x -= mmp.getOrigin().x;
        ptTmp.y -= mmp.getOrigin().y;
        ptCoarse.x = ptTmp.x / mmp.getTileWidth();
        ptCoarse.y = ptTmp.y / mmp.getTileHeight();
        ptTmp.x %= mmp.getTileWidth();
        ptTmp.y %= mmp.getTileHeight();
        if (ptTmp.x < 0) {
            ptCoarse.x--;
        }
        if (ptTmp.y < 0) {
            ptCoarse.y--;
        }
        //指定左下角点MAP(coarse)/////////
        ptMap.x = 0;
        ptMap.y = 0;
        ptMap = walker.tileWalk(ptMap, Direction.EAST);
        ptCornerLowerLeft.x = ptMap.x * ptCoarse.x;
        ptCornerLowerLeft.y = ptMap.y * ptCoarse.x;
        ptMap.x = 0;
        ptMap.y = 0;
        ptMap = walker.tileWalk(ptMap, Direction.SOUTH);
        ptCornerLowerLeft.x += (ptMap.x *= ptCoarse.y);
        ptCornerLowerLeft.y += (ptMap.y *= ptCoarse.y);

        //=================右下=================
        ptTmp.x = (int) rcUpdate.getMaxX();
        ptTmp.y = (int) rcUpdate.getMaxY();

        ptTmp = scroller.screenToWorld(ptTmp);
        ptTmp.x -= mmp.getOrigin().x;
        ptTmp.y -= mmp.getOrigin().y;
        ptCoarse.x = ptTmp.x / mmp.getTileWidth();
        ptCoarse.y = ptTmp.y / mmp.getTileHeight();
        ptTmp.x %= mmp.getTileWidth();
        ptTmp.y %= mmp.getTileHeight();
        if (ptTmp.x < 0) {
            ptCoarse.x--;
        }
        if (ptTmp.y < 0) {
            ptCoarse.y--;
        }
        //指定右下角点MAP(coarse)/////////
        ptMap.x = 0;
        ptMap.y = 0;
        ptMap = walker.tileWalk(ptMap, Direction.EAST);
        ptCornerLowerRight.x = ptMap.x * ptCoarse.x;
        ptCornerLowerRight.y = ptMap.y * ptCoarse.x;
        ptMap.x = 0;
        ptMap.y = 0;
        ptMap = walker.tileWalk(ptMap, Direction.SOUTH);
        ptCornerLowerRight.x += (ptMap.x * ptCoarse.y);
        ptCornerLowerRight.y += (ptMap.y * ptCoarse.y);
        //=============至此四角(coarse)定义完成===================
        //四个角都向外的扩一步
        ptCornerUpperLeft = walker.tileWalk(ptCornerUpperLeft, Direction.NORTHWEST);
        ptCornerUpperRight = walker.tileWalk(ptCornerUpperRight, Direction.NORTHEAST);
        ptCornerLowerLeft = walker.tileWalk(ptCornerLowerLeft, Direction.SOUTHWEST);
        ptCornerLowerRight = walker.tileWalk(ptCornerLowerRight, Direction.SOUTHEAST);

        //TODO 下载四行代码非必要,若有"边界精灵显示怪异",可应用下面四行代码适当再扩展渲染范围
        //左上角向左一步  右上角向左一步 
//        TODO 在原代码基础上改更，使diamom图不会死循环
//        ptCornerUpperLeft=walker.tileWalk(ptCornerUpperLeft, Direction.WEST);
//        ptCornerUpperRight=walker.tileWalk(ptCornerUpperRight, Direction.EAST);
//        左下角向下一步 右下角向下一步
        
        ptMap.x = 0;
        ptMap.y = 0;
        ptMap=walker.tileWalk(ptMap, Direction.NORTH);
        ptCornerUpperLeft.x+=ptMap.x*scale;
        ptCornerUpperLeft.y+=ptMap.y*scale; 
        
        ptCornerUpperRight.x+=ptMap.x*scale;
        ptCornerUpperRight.y+=ptMap.y*scale;
        
        
        ptMap.x = 0;
        ptMap.y = 0;
        ptMap=walker.tileWalk(ptMap, Direction.SOUTH);
        ptCornerLowerLeft.x+=ptMap.x*scale;
        ptCornerLowerLeft.y+=ptMap.y*scale; 
        
        ptCornerLowerRight.x+=ptMap.x*scale;
        ptCornerLowerRight.y+=ptMap.y*scale;
        
        
        ptMap.x = 0;
        ptMap.y = 0;
        ptMap=walker.tileWalk(ptMap, Direction.WEST);
        ptCornerUpperLeft.x+=ptMap.x*scale;
        ptCornerUpperLeft.y+=ptMap.y*scale; 
        ptCornerLowerLeft.x+=ptMap.x*scale;
        ptCornerLowerLeft.y+=ptMap.y*scale; 
        ptMap.x = 0;
        ptMap.y = 0;
        ptMap=walker.tileWalk(ptMap, Direction.EAST);
        ptCornerUpperRight.x+=ptMap.x*scale;
        ptCornerUpperRight.y+=ptMap.y*scale; 
        ptCornerLowerRight.x+=ptMap.x*scale;
        ptCornerLowerRight.y+=ptMap.y*scale; 
        
        
        

        Point ptRowStart = ptCornerUpperLeft;
        Point ptRowEnd = ptCornerUpperRight;
        Point ptCurrent = ptRowStart;
        int rowCount = 0;
        for (;;) {
            ptCurrent = ptRowStart;// 
//            System.out.println("ptCurrent "+ptCurrent+" ~ "+ptCornerLowerLeft);
            for (;;) {// redners a row of tiles
                if (ptCurrent.x >= 0 && ptCurrent.y >= 0
                        && ptCurrent.x < mapWidth && ptCurrent.y < mapHeight) {
                    
                    bMap[ptCurrent.x + ptCurrent.y * mapWidth] = true;
                    
                }//end if
                if (ptCurrent.x == ptRowEnd.x && ptCurrent.y == ptRowEnd.y) {
                    break;
                }
                ptCurrent = walker.tileWalk(ptCurrent, Direction.EAST);
//                System.out.println("\t "+ptCurrent);
            }//内部for end
            //check to see if this is the last row
//            if (ptRowStart.x == ptCornerLowerLeft.x && ptRowStart.y == ptCornerLowerLeft.y) {
//                break;
//            }
            if ( ptRowStart.y >=ptCornerLowerLeft.y) {
                break;
            }
//            System.out.println("ptCurrent "+ptCurrent+" ~ "+ptCornerLowerLeft);
//                System.out.println("ptCornerLowerLeft "+ptCornerLowerLeft);
            //move down a row
            if ((rowCount & 0x1) !=0) {
//                System.out.println("奇");
                //odd row 奇行
                //move outward
                ptRowStart = walker.tileWalk(ptRowStart, Direction.SOUTHWEST);
                ptRowEnd = walker.tileWalk(ptRowEnd, Direction.SOUTHEAST);
            } else {
//                System.out.println("偶");
                //even row 偶行
                //move inward
                ptRowStart = walker.tileWalk(ptRowStart, Direction.SOUTHEAST);
                ptRowEnd = walker.tileWalk(ptRowEnd, Direction.SOUTHWEST);
            }

            //add one to the row count
            rowCount++;
        }//for end
//        System.out.println("rowCount "+rowCount);
        return true;
    }
    
    public void updateFrame() {
        if (!isExtremeEfficiency()) {
            Rectangle s = te.getScreenSpace();
            Color oldc = gOffScreen.getColor();
            gOffScreen.setColor(Color.BLACK);//TODO 背景色 
            gOffScreen.fillRect(s.x, s.y, s.width, s.height);
            gOffScreen.setColor(oldc);
            
        }

        
        Point ptCornerUpperLeft=new Point();
        Point ptCornerUpperRight=new Point();
        Point ptCornerLowerLeft=new Point();
        Point ptCornerLowerRight=new Point();
        
        Point ptTmp=new Point();
        Point ptCoarse=new Point();
        Point ptMap=new Point();
        Point ptPlot=new Point();
        Rectangle screenSpace=scroller.getScreeSpace();
        //=================左上=================
        ptTmp.x=screenSpace.x;
        ptTmp.y=screenSpace.y;
        /////
        ptTmp=scroller.screenToWorld(ptTmp);
        ptTmp.x-=mmp.getOrigin().x;
        ptTmp.y-=mmp.getOrigin().y;
        ptCoarse.x=ptTmp.x/mmp.getTileWidth();
        ptCoarse.y=ptTmp.y/mmp.getTileHeight();
        ptTmp.x%=mmp.getTileWidth();
        ptTmp.y%=mmp.getTileHeight();
        if(ptTmp.x<0) ptCoarse.x--;
        if(ptTmp.y<0) ptCoarse.y--;
        //指定左上角点MAP(coarse)/////////
        ptMap.x=0;ptMap.y=0;
        ptMap =walker.tileWalk(ptMap, Direction.EAST);
        ptCornerUpperLeft.x=ptMap.x*ptCoarse.x;
        ptCornerUpperLeft.y=ptMap.y*ptCoarse.x;
        ptMap.x=0;ptMap.y=0;
        ptMap =walker.tileWalk(ptMap, Direction.SOUTH);
        ptCornerUpperLeft.x+=(ptMap.x*ptCoarse.y);
        ptCornerUpperLeft.y+=(ptMap.y*ptCoarse.y);
        //=================右上=================
        ptTmp.x=(int) screenSpace.getMaxX();
        ptTmp.y=screenSpace.y;
        ///////
        ptTmp=scroller.screenToWorld(ptTmp);
        ptTmp.x-=mmp.getOrigin().x;
        ptTmp.y-=mmp.getOrigin().y;
        ptCoarse.x=ptTmp.x/mmp.getTileWidth();
        ptCoarse.y=ptTmp.y/mmp.getTileHeight();
        ptTmp.x%=mmp.getTileWidth();
        ptTmp.y%=mmp.getTileHeight();
        if(ptTmp.x<0) ptCoarse.x--;
        if(ptTmp.y<0) ptCoarse.y--;
        //指定右上角点MAP(coarse)/////////
        ptMap.x=0;ptMap.y=0;
        ptMap =walker.tileWalk(ptMap, Direction.EAST);
        ptCornerUpperRight.x=ptMap.x*ptCoarse.x;
        ptCornerUpperRight.y=ptMap.y*ptCoarse.x;
	ptMap.x=0;
	ptMap.y=0;
	//move to the south
	ptMap=walker.tileWalk(ptMap,Direction.SOUTH);
	ptCornerUpperRight.x+=(ptMap.x*ptCoarse.y);
	ptCornerUpperRight.y+=(ptMap.y*ptCoarse.y);
        //=================左下=================
        ptTmp.x=screenSpace.x;
        ptTmp.y=(int) screenSpace.getMaxY();
        ////
        ptTmp=scroller.screenToWorld(ptTmp);
        ptTmp.x-=mmp.getOrigin().x;
        ptTmp.y-=mmp.getOrigin().y;
        ptCoarse.x=ptTmp.x/mmp.getTileWidth();
        ptCoarse.y=ptTmp.y/mmp.getTileHeight();
        ptTmp.x%=mmp.getTileWidth();
        ptTmp.y%=mmp.getTileHeight();
        if(ptTmp.x<0) ptCoarse.x--;
        if(ptTmp.y<0) ptCoarse.y--;
        //指定左下角点MAP(coarse)/////////
        ptMap.x=0;ptMap.y=0;
        ptMap =walker.tileWalk(ptMap, Direction.EAST);
        ptCornerLowerLeft.x=ptMap.x*ptCoarse.x;
        ptCornerLowerLeft.y=ptMap.y*ptCoarse.x;
        ptMap.x=0;ptMap.y=0;
        ptMap =walker.tileWalk(ptMap, Direction.SOUTH);
        ptCornerLowerLeft.x+=(ptMap.x*=ptCoarse.y);
        ptCornerLowerLeft.y+=(ptMap.y*=ptCoarse.y);
        
        //=================右下=================
        ptTmp.x=(int) screenSpace.getMaxX();
        ptTmp.y=(int) screenSpace.getMaxY();
        
        ptTmp=scroller.screenToWorld(ptTmp);
        ptTmp.x-=mmp.getOrigin().x;
        ptTmp.y-=mmp.getOrigin().y;
        ptCoarse.x=ptTmp.x/mmp.getTileWidth();
        ptCoarse.y=ptTmp.y/mmp.getTileHeight();
        ptTmp.x%=mmp.getTileWidth();
        ptTmp.y%=mmp.getTileHeight();
        if(ptTmp.x<0) ptCoarse.x--;
        if(ptTmp.y<0) ptCoarse.y--;
        //指定右下角点MAP(coarse)/////////
        ptMap.x=0;ptMap.y=0;
        ptMap =walker.tileWalk(ptMap, Direction.EAST);
        ptCornerLowerRight.x=ptMap.x*ptCoarse.x;
        ptCornerLowerRight.y=ptMap.y*ptCoarse.x;
        ptMap.x=0;ptMap.y=0;
        ptMap =walker.tileWalk(ptMap, Direction.SOUTH);
        ptCornerLowerRight.x+=(ptMap.x*ptCoarse.y);
        ptCornerLowerRight.y+=(ptMap.y*ptCoarse.y);
        //=============至此四角(coarse)定义完成===================
        //四个角都向外的扩一步
        ptCornerUpperLeft=walker.tileWalk(ptCornerUpperLeft, Direction.NORTHWEST);
        ptCornerUpperRight=walker.tileWalk(ptCornerUpperRight, Direction.NORTHEAST);
        ptCornerLowerLeft=walker.tileWalk(ptCornerLowerLeft, Direction.SOUTHWEST);
        ptCornerLowerRight=walker.tileWalk(ptCornerLowerRight, Direction.SOUTHEAST);
        
//        ptCornerUpperLeft=walker.tileWalk(ptCornerUpperLeft, Direction.NORTHWEST);
//        ptCornerUpperRight=walker.tileWalk(ptCornerUpperRight, Direction.NORTHEAST);
//        ptCornerLowerLeft=walker.tileWalk(ptCornerLowerLeft, Direction.SOUTHWEST);
//        ptCornerLowerRight=walker.tileWalk(ptCornerLowerRight, Direction.SOUTHEAST);
        //TODO 下载四行代码非必要,若有"边界精灵显示怪异",可应用下面四行代码适当再扩展渲染范围
        //左上角向左一步  右上角向左一步 
//        ptCornerUpperLeft=walker.tileWalk(ptCornerUpperLeft, Direction.WEST);
//        ptCornerUpperRight=walker.tileWalk(ptCornerUpperRight, Direction.WEST);
        //左下角向下一步 右下角向下一步
//        ptCornerLowerLeft=walker.tileWalk(ptCornerLowerLeft, Direction.SOUTH);
//        ptCornerLowerRight=walker.tileWalk(ptCornerLowerRight, Direction.SOUTH);
        
        //TODO 下载四行代码非必要,若有"边界精灵显示怪异",可应用下面四行代码适当再扩展渲染范围
        //左上角向左一步  右上角向左一步 
        //TODO 在原代码基础上改更，使diamom图不会死循环
//        ptCornerUpperLeft=walker.tileWalk(ptCornerUpperLeft, Direction.WEST);
//        ptCornerUpperRight=walker.tileWalk(ptCornerUpperRight, Direction.EAST);
//        //左下角向下一步 右下角向下一步
//        ptCornerLowerLeft=walker.tileWalk(ptCornerLowerLeft, Direction.SOUTH);
//        ptCornerLowerRight=walker.tileWalk(ptCornerLowerRight, Direction.SOUTH);
//        ptCornerLowerLeft=walker.tileWalk(ptCornerLowerLeft, Direction.WEST);
//        ptCornerLowerRight=walker.tileWalk(ptCornerLowerRight, Direction.EAST);
        
        if(isExtremeEfficiency()){
        ptMap.x = 0;
        ptMap.y = 0;
        ptMap=walker.tileWalk(ptMap, Direction.NORTH);
        ptCornerUpperLeft.x+=ptMap.x*scale;
        ptCornerUpperLeft.y+=ptMap.y*scale; 
        
        ptCornerUpperRight.x+=ptMap.x*scale;
        ptCornerUpperRight.y+=ptMap.y*scale;
        
        
        ptMap.x = 0;
        ptMap.y = 0;
        ptMap=walker.tileWalk(ptMap, Direction.SOUTH);
        ptCornerLowerLeft.x+=ptMap.x*scale;
        ptCornerLowerLeft.y+=ptMap.y*scale; 
        
        ptCornerLowerRight.x+=ptMap.x*scale;
        ptCornerLowerRight.y+=ptMap.y*scale;
        
        
        ptMap.x = 0;
        ptMap.y = 0;
        ptMap=walker.tileWalk(ptMap, Direction.WEST);
        ptCornerUpperLeft.x+=ptMap.x*scale;
        ptCornerUpperLeft.y+=ptMap.y*scale; 
        ptCornerLowerLeft.x+=ptMap.x*scale;
        ptCornerLowerLeft.y+=ptMap.y*scale; 
        ptMap.x = 0;
        ptMap.y = 0;
        ptMap=walker.tileWalk(ptMap, Direction.EAST);
        ptCornerUpperRight.x+=ptMap.x*scale;
        ptCornerUpperRight.y+=ptMap.y*scale; 
        ptCornerLowerRight.x+=ptMap.x*scale;
        ptCornerLowerRight.y+=ptMap.y*scale; 
        }
        
        int printCount=0;
        
        int layerSize=1;
        boolean isMapScaleLayering=scene.isBasedMapScaleLayering();
//        System.out.println("isMapScaleLayering "+isMapScaleLayering);
//        System.out.println("scene.getLayerSize() "+scene.getLayerSize());
        if(isMapScaleLayering)layerSize=scene.getLayerSize();
        for(int layerIdx=0;layerIdx<layerSize;layerIdx++){
            Point ptRowStart = new Point(ptCornerUpperLeft);
            Point ptRowEnd = new Point(ptCornerUpperRight);
            Point ptCurrent =  new Point(ptRowStart);
            int rowCount = 0;
            for(;;){
                ptCurrent=ptRowStart;
                for(;;){// redners a row of tiles
                    if (ptCurrent.x >= 0 && ptCurrent.y >= 0
                            && ptCurrent.x < mapWidth && ptCurrent.y < mapHeight) {
                        if (isExtremeEfficiency()) {
                            if (bMap[ptCurrent.x + ptCurrent.y * mapWidth] == true) {
                                ptPlot = plotter.plotTile(ptCurrent); //map to world
                                ptPlot = scroller.worldToScreen(ptPlot);//world to screen
    //                            scene.render(gOffScreen, screenSpace, ptPlot.x, ptPlot.y, ptCurrent);
                                scene.render(gFrameBuffer, screenSpace, ptPlot.x, ptPlot.y, ptCurrent,isMapScaleLayering?layerIdx:-1);
                                printCount++;
                                if(!isMapScaleLayering ||( isMapScaleLayering && layerIdx==(layerSize-1)) ){
                                    bMap[ptCurrent.x + ptCurrent.y * mapWidth] = false;
                                }
                                    
                            }
                        } else { //一般渲染
                                ptPlot = plotter.plotTile(ptCurrent); //map to world
                                ptPlot = scroller.worldToScreen(ptPlot);//world to screen
                                printCount++;
                                scene.render(gOffScreen, screenSpace, ptPlot.x, ptPlot.y, ptCurrent,isMapScaleLayering?layerIdx:-1);
                        }//render end if 
                    }//end if
                    if(ptCurrent.x==ptRowEnd.x && ptCurrent.y==ptRowEnd.y) break;//TODO 条件检测有问题,可能会到无穷循环情况 用>
                    ptCurrent=walker.tileWalk(ptCurrent, Direction.EAST);
                }//内部 col for end
                //check to see if this is the last row
                if (ptRowStart.x == ptCornerLowerLeft.x && ptRowStart.y == ptCornerLowerLeft.y) {
                    break;
                }

                //move down a row
                if ((rowCount & 1) == 1) {
                    //odd row 奇行
                    //move outward
                    ptRowStart = walker.tileWalk(ptRowStart, Direction.SOUTHWEST);
                    ptRowEnd = walker.tileWalk(ptRowEnd, Direction.SOUTHEAST);
                } else {
                    //even row 偶行
                    //move inward
                    ptRowStart = walker.tileWalk(ptRowStart, Direction.SOUTHEAST);
                    ptRowEnd = walker.tileWalk(ptRowEnd, Direction.SOUTHWEST);
                }

                //add one to the row count
                rowCount++;
            }//row for end
        }//layer for end
        if(printCount!=0)
            System.out.println("[Render.updateFrame ]printCount "+printCount);
//        int bcount=0;
//        for(int i=0;i< bMap.length;i++){
//            if(bMap[i]==true){
//                bcount++;
//            }
//        }
//        if(bcount!=0)
//            System.out.println("[Render.updateFrame ] bcount"+bcount);
        for(int idx=0;idx<maxUpdateCaptical;idx++){
            Rectangle box=updateBoxes[idx];
            if(box !=null){
                gOffScreen.drawImage(frameBuffer, box.x , box.y,(int) box.getMaxX(), (int)box.getMaxY(), 
                        box.x , box.y,(int) box.getMaxX(), (int)box.getMaxY(),null);
                updateBoxes[idx]=null;
            }
        }
        if(iUpdateRectIdx!=0)
        gFrameBuffer.drawImage(offScreenImage, 0 , 0, null);
        iUpdateRectIdx=0;
        
        
    }
     public void efficientPaint(Graphics2D g){
        
        Point ptCornerUpperLeft=new Point();
        Point ptCornerUpperRight=new Point();
        Point ptCornerLowerLeft=new Point();
        Point ptCornerLowerRight=new Point();
        
        Point ptTmp=new Point();
        Point ptCoarse=new Point();
        Point ptMap=new Point();
        Point ptPlot=new Point();
        Rectangle screenSpace=scroller.getScreeSpace();
        //=================左上=================
        ptTmp.x=screenSpace.x;
        ptTmp.y=screenSpace.y;
        /////
        ptTmp=scroller.screenToWorld(ptTmp);
        ptTmp.x-=mmp.getOrigin().x;
        ptTmp.y-=mmp.getOrigin().y;
        ptCoarse.x=ptTmp.x/mmp.getTileWidth();
        ptCoarse.y=ptTmp.y/mmp.getTileHeight();
        ptTmp.x%=mmp.getTileWidth();
        ptTmp.y%=mmp.getTileHeight();
        if(ptTmp.x<0) ptCoarse.x--;
        if(ptTmp.y<0) ptCoarse.y--;
        //指定左上角点MAP(coarse)/////////
        ptMap.x=0;ptMap.y=0;
        ptMap =walker.tileWalk(ptMap, Direction.EAST);
        ptCornerUpperLeft.x=ptMap.x*ptCoarse.x;
        ptCornerUpperLeft.y=ptMap.y*ptCoarse.x;
        ptMap.x=0;ptMap.y=0;
        ptMap =walker.tileWalk(ptMap, Direction.SOUTH);
        ptCornerUpperLeft.x+=(ptMap.x*ptCoarse.y);
        ptCornerUpperLeft.y+=(ptMap.y*ptCoarse.y);
        //=================右上=================
        ptTmp.x=(int) screenSpace.getMaxX();
        ptTmp.y=screenSpace.y;
        ///////
        ptTmp=scroller.screenToWorld(ptTmp);
        ptTmp.x-=mmp.getOrigin().x;
        ptTmp.y-=mmp.getOrigin().y;
        ptCoarse.x=ptTmp.x/mmp.getTileWidth();
        ptCoarse.y=ptTmp.y/mmp.getTileHeight();
        ptTmp.x%=mmp.getTileWidth();
        ptTmp.y%=mmp.getTileHeight();
        if(ptTmp.x<0) ptCoarse.x--;
        if(ptTmp.y<0) ptCoarse.y--;
        //指定右上角点MAP(coarse)/////////
        ptMap.x=0;ptMap.y=0;
        ptMap =walker.tileWalk(ptMap, Direction.EAST);
        ptCornerUpperRight.x=ptMap.x*ptCoarse.x;
        ptCornerUpperRight.y=ptMap.y*ptCoarse.x;
	ptMap.x=0;
	ptMap.y=0;
	//move to the south
	ptMap=walker.tileWalk(ptMap,Direction.SOUTH);
	ptCornerUpperRight.x+=(ptMap.x*ptCoarse.y);
	ptCornerUpperRight.y+=(ptMap.y*ptCoarse.y);
        //=================左下=================
        ptTmp.x=screenSpace.x;
        ptTmp.y=(int) screenSpace.getMaxY();
        ////
        ptTmp=scroller.screenToWorld(ptTmp);
        ptTmp.x-=mmp.getOrigin().x;
        ptTmp.y-=mmp.getOrigin().y;
        ptCoarse.x=ptTmp.x/mmp.getTileWidth();
        ptCoarse.y=ptTmp.y/mmp.getTileHeight();
        ptTmp.x%=mmp.getTileWidth();
        ptTmp.y%=mmp.getTileHeight();
        if(ptTmp.x<0) ptCoarse.x--;
        if(ptTmp.y<0) ptCoarse.y--;
        //指定左下角点MAP(coarse)/////////
        ptMap.x=0;ptMap.y=0;
        ptMap =walker.tileWalk(ptMap, Direction.EAST);
        ptCornerLowerLeft.x=ptMap.x*ptCoarse.x;
        ptCornerLowerLeft.y=ptMap.y*ptCoarse.x;
        ptMap.x=0;ptMap.y=0;
        ptMap =walker.tileWalk(ptMap, Direction.SOUTH);
        ptCornerLowerLeft.x+=(ptMap.x*=ptCoarse.y);
        ptCornerLowerLeft.y+=(ptMap.y*=ptCoarse.y);
        
        //=================右下=================
        ptTmp.x=(int) screenSpace.getMaxX();
        ptTmp.y=(int) screenSpace.getMaxY();
        
        ptTmp=scroller.screenToWorld(ptTmp);
        ptTmp.x-=mmp.getOrigin().x;
        ptTmp.y-=mmp.getOrigin().y;
        ptCoarse.x=ptTmp.x/mmp.getTileWidth();
        ptCoarse.y=ptTmp.y/mmp.getTileHeight();
        ptTmp.x%=mmp.getTileWidth();
        ptTmp.y%=mmp.getTileHeight();
        if(ptTmp.x<0) ptCoarse.x--;
        if(ptTmp.y<0) ptCoarse.y--;
        //指定右下角点MAP(coarse)/////////
        ptMap.x=0;ptMap.y=0;
        ptMap =walker.tileWalk(ptMap, Direction.EAST);
        ptCornerLowerRight.x=ptMap.x*ptCoarse.x;
        ptCornerLowerRight.y=ptMap.y*ptCoarse.x;
        ptMap.x=0;ptMap.y=0;
        ptMap =walker.tileWalk(ptMap, Direction.SOUTH);
        ptCornerLowerRight.x+=(ptMap.x*ptCoarse.y);
        ptCornerLowerRight.y+=(ptMap.y*ptCoarse.y);
        //=============至此四角(coarse)定义完成===================
        //四个角都向外的扩一步
        ptCornerUpperLeft=walker.tileWalk(ptCornerUpperLeft, Direction.NORTHWEST);
        ptCornerUpperRight=walker.tileWalk(ptCornerUpperRight, Direction.NORTHEAST);
        ptCornerLowerLeft=walker.tileWalk(ptCornerLowerLeft, Direction.SOUTHWEST);
        ptCornerLowerRight=walker.tileWalk(ptCornerLowerRight, Direction.SOUTHEAST);
        //TODO 下载四行代码非必要,若有"边界精灵显示怪异",可应用下面四行代码适当再扩展渲染范围
        //左上角向左一步  右上角向左一步 
//        ptCornerUpperLeft=walker.tileWalk(ptCornerUpperLeft, Direction.WEST);
//        ptCornerUpperRight=walker.tileWalk(ptCornerUpperRight, Direction.WEST);
        //左下角向下一步 右下角向下一步
//        ptCornerLowerLeft=walker.tileWalk(ptCornerLowerLeft, Direction.SOUTH);
//        ptCornerLowerRight=walker.tileWalk(ptCornerLowerRight, Direction.SOUTH);
        
        
        int layerSize=1;
        boolean isMapScaleLayering=scene.isBasedMapScaleLayering();
        if(isMapScaleLayering)layerSize=scene.getLayerSize();
        for(int layerIdx=0;layerIdx<layerSize;layerIdx++){
            Point ptRowStart = new Point(ptCornerUpperLeft);
            Point ptRowEnd = new Point(ptCornerUpperRight);
            Point ptCurrent = new Point(ptRowStart);
            int rowCount = 0;
            for(;;){
                ptCurrent=ptRowStart;
                for(;;){// redners a row of tiles
                    if (ptCurrent.x >= 0 && ptCurrent.y >= 0
                            && ptCurrent.x < mapWidth && ptCurrent.y < mapHeight) {
                        //渲染
                        ptPlot = plotter.plotTile(ptCurrent); //map to world
                        ptPlot = scroller.worldToScreen(ptPlot);//world to screen
    //                    scene.tileSet.put(g, ptPlot.x, ptPlot.y,
    //                            scene.mapArr[ptCurrent.x][ptCurrent.y]);
    //                    ((CustomScene1)scene).tileSet.efficientPut(g, screenSpace,ptPlot.x, ptPlot.y,
    //                            ((CustomScene1)scene).mapArr[ptCurrent.x][ptCurrent.y]);
                        scene.render(g, screenSpace,ptPlot.x, ptPlot.y,ptCurrent,isMapScaleLayering?layerIdx:-1);
//                        bMap[ptCurrent.x+ptCurrent.y*mapWidth]=true;
                    }//end if
                    if(ptCurrent.x==ptRowEnd.x && ptCurrent.y==ptRowEnd.y) break;
                    ptCurrent=walker.tileWalk(ptCurrent, Direction.EAST);
                }//内部for end
                //check to see if this is the last row
                if (ptRowStart.x == ptCornerLowerLeft.x && ptRowStart.y == ptCornerLowerLeft.y) {
                    break;
                }

                //move down a row
                if ((rowCount & 1) == 1) {
                    //odd row 奇行
                    //move outward
                    ptRowStart = walker.tileWalk(ptRowStart, Direction.SOUTHWEST);
                    ptRowEnd = walker.tileWalk(ptRowEnd, Direction.SOUTHEAST);
                } else {
                    //even row 偶行
                    //move inward
                    ptRowStart = walker.tileWalk(ptRowStart, Direction.SOUTHEAST);
                    ptRowEnd = walker.tileWalk(ptRowEnd, Direction.SOUTHWEST);
                }

                //add one to the row count
                rowCount++;
            }//row for end
        }//layer for end
//         System.out.println("[renderer]打印数"+paintCount);
        /****
	DWORD dwRowCount=0;
        for(;;)
	{
		//set current point to rowstart
		ptCurrent=ptRowStart;

		//render a row of tiles
		for(;;)
		{
			//plot the tile
			ptPlot=pTilePlotter->PlotTile(ptCurrent);
			ptPlot=pScroller->WorldToScreen(ptPlot);
			//check that ptcurrent is an actual map location
			if(ptCurrent.x>=0 && ptCurrent.y>=0 && ptCurrent.x<iMapWidth && ptCurrent.y<iMapHeight)
			{
				//is the tile marked?
				if(bMap[ptCurrent.x+ptCurrent.y*iMapWidth])
				{
					//send to rendering function
					RenderFunction(lpddsFrameBuffer,&rcUpdate,ptPlot.x,ptPlot.y,ptCurrent.x,ptCurrent.y);
					//rest to unmarked
					bMap[ptCurrent.x+ptCurrent.y*iMapWidth]=false;
				}
			}

			//is this the last tile in the row?
			if(ptCurrent.x==ptRowEnd.x && ptCurrent.y==ptRowEnd.y) break;

			//walk to the east
			ptCurrent=pTileWalker->TileWalk(ptCurrent,ISO_EAST);

		}

		//check to see if this is the last row
		if(ptRowStart.x==ptCornerLowerLeft.x && ptRowStart.y==ptCornerLowerLeft.y) break;

		//move down a row
		if(dwRowCount&1)
		{
			//odd row
			//move outward
			ptRowStart=pTileWalker->TileWalk(ptRowStart,ISO_SOUTHWEST);
			ptRowEnd=pTileWalker->TileWalk(ptRowEnd,ISO_SOUTHEAST);
		}
		else
		{
			//even row
			//move inward
			ptRowStart=pTileWalker->TileWalk(ptRowStart,ISO_SOUTHEAST);
			ptRowEnd=pTileWalker->TileWalk(ptRowEnd,ISO_SOUTHWEST);
		}

		//add one to the row count
		dwRowCount++;
	}

	//render all update rects from frame buffer to back buffer
	for(int iCount=0;iCount<iUpdateRectIndex;iCount++)
	{
		//render update rect
		lpddsBackBuffer->BltFast(rcUpdateList[iCount].left,rcUpdateList[iCount].top,lpddsFrameBuffer,&rcUpdateList[iCount],DDBLTFAST_WAIT);
	}

	//render from back buffer to frame buffer
	lpddsFrameBuffer->BltFast(rcUpdate.left,rcUpdate.top,lpddsBackBuffer,&rcUpdate,DDBLTFAST_WAIT);

	//set rectangle index to 0
	iUpdateRectIndex=0;
         */
        
        
        
    }

    public boolean[] getbMap() {
        return bMap;
    }
     
}
